﻿using Microsoft.VisualStudio.TestTools.UITest.Common;
using Microsoft.VisualStudio.TestTools.UITest.Extension;
using System;
using System.Collections.Generic;
using System.Linq;

namespace AXExtension.Filters
{
	/// <summary>
	/// This filter changes window titles so that they
	/// only include letters, excluding text inside 
	/// parentheses.
	/// </summary>
	class WindowTitleFilter : Filter
	{
		private HashSet<string> usedStrings = new HashSet<string>();

		public WindowTitleFilter()
		{
			Require(stack => !string.IsNullOrEmpty(stack.Peek().UIElement.TopLevelElement.Name));
		}

		public override void Run(IUITestActionStack stack)
		{
			UITestAction action = stack.Peek();
			// To make sure a window isn't identified accidentally
			// we make sure that no title fragment is used twice.
			IEnumerable<string> fragments = LetterFragments(action.UIElement.TopLevelElement.Name);

			var conditions = new List<IQueryCondition>(
				fragments.Select(s =>
					new PropertyCondition("Name", s, PropertyConditionOperator.Contains)));
				
			// We have to preserve other conditions the
			// the window has, so we go through and collect
			// them.
			foreach (var condition in (action.UIElement.TopLevelElement.QueryId.Condition as AndCondition).Conditions)
			{
				if (condition is PropertyCondition &&
					(condition as PropertyCondition).PropertyName != "Name")
				{
					conditions.Add(condition);
				}
			}

			action.UIElement.TopLevelElement.QueryId.Condition = new AndCondition(conditions.ToArray());
		}

		private IEnumerable<string> LetterFragments(string str)
		{
			return str
				.Split("1234567890()[]:-".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
				.Where(s => !string.IsNullOrWhiteSpace(s))
				.Select(StringExtensions.OnlyNormals)
				.Select(s => s.Trim())
				.Where(s => s.Length > 2)
				.OrderByDescending(s => s.Length)
				.Take(2);
		}

		
	}
}
